#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h>

// 定义等待队列头
static wait_queue_head_t my_wait_queue;
// 定义等待队列项
static struct wait_queue_entry my_wait;
// 定义一个标志，用于表示是否有写入操作
static int data_written = 0;
// 定义 proc 文件项
static struct proc_dir_entry *my_proc_entry;

// 等待队列项的回调函数
static int my_wakeup_function(struct wait_queue_entry *wq_entry, unsigned mode,
			      int sync, void *key)
{
	return data_written;
}

// proc 文件的写入函数
static ssize_t my_proc_write(struct file *file, const char __user *buf,
			     size_t count, loff_t *f_pos)
{
	// 设置标志，表示有写入操作
	data_written = 1;
	// 唤醒等待队列中的进程
	wake_up(&my_wait_queue);
	return count;
}

// proc 文件操作结构体
static const struct proc_ops my_proc_fops = {
	.proc_write = my_proc_write,
};

// 模块初始化函数
static int __init my_module_init(void)
{
	// 初始化等待队列头
	init_waitqueue_head(&my_wait_queue);
	// 初始化等待队列项
	init_waitqueue_entry(&my_wait, current);
	// 设置等待队列项的回调函数
	my_wait.func = my_wakeup_function;
	// 将等待队列项添加到等待队列头
	add_wait_queue(&my_wait_queue, &my_wait);

	// 创建 proc 文件
	my_proc_entry = proc_create("my_proc_file", 0222, NULL, &my_proc_fops);
	if (!my_proc_entry) {
		printk(KERN_ERR "Failed to create proc entry\n");
		return -ENOMEM;
	}

	// 将当前进程设置为可中断睡眠状态
	set_current_state(TASK_INTERRUPTIBLE);
	// 调度出去，等待事件发生
	schedule();

	printk(KERN_INFO "Module initialized and woken up\n");
	return 0;
}

// 模块退出函数
static void __exit my_module_exit(void)
{
	// 移除等待队列项
	remove_wait_queue(&my_wait_queue, &my_wait);
	// 删除 proc 文件
	remove_proc_entry("my_proc_file", NULL);
	printk(KERN_INFO "Module exited\n");
}

// 注册模块初始化和退出函数
module_init(my_module_init);
module_exit(my_module_exit);

// 模块许可证声明
MODULE_LICENSE("GPL");
// 模块作者信息
MODULE_AUTHOR("Your Name");
// 模块描述信息
MODULE_DESCRIPTION(
	"A module demonstrating wait queue and proc file interaction");